//
//  WmcSliderView.swift
//  YPWatermarkCamera
//
//  Created by 赵新 on 2022/6/14.
//

import UIKit
import YPBedrock

extension WmcSliderView {
    struct Model {
        var title: String?
        var progress: CGFloat
    }
}

// MARK: - [WmcSliderView]

class WmcSliderView: WmcBaseView {
    // Lifecycle

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    /// 实例化
    /// - Parameters:
    ///   - values: 值组
    ///   - isScrollToStep: 是否滑动校准
    convenience init(values: [Model],
                     isScrollToStep: Bool = true)
    {
        self.init(frame: .zero)
        self.values = values
        self.isScrollToStep = isScrollToStep
        _makeUI()
    }

    // Internal

    lazy var maskLineView: UIView = {
        let view = UIView()
        return view
    }()

    lazy var maskLayer: CAShapeLayer = {
        let maskLayer = CAShapeLayer()
        return maskLayer
    }()

    lazy var progressLineView: UIView = {
        let view = UIView()
        view.backgroundColor = .wmc_mainTheme
        return view
    }()

    lazy var controlView: UIView = {
        let view = UIView()
        view.isUserInteractionEnabled = true
        return view
    }()
    
    lazy var controlPointView: UIView = {
        let view = UIView()
        view.isUserInteractionEnabled = true
        view.backgroundColor = .white
        view.layer.shadowColor = UIColor.black.cgColor
        view.layer.shadowOpacity = 0.47
        view.layer.shadowOffset = .zero
        return view
    }()

    /// 拖拽
    lazy var panGesture: UIPanGestureRecognizer = {
        let gesture = UIPanGestureRecognizer.YP.Create { [weak self] pan in
            guard let weakSelf = self else { return }
            let translation = pan.translation(in: weakSelf.controlView)
            guard let panView = pan.view else { return }
            pan.setTranslation(CGPoint.zero, in: weakSelf.controlView) // 归零
            var x = panView.center.x + translation.x
            let minX = weakSelf.maskLineView.frame.origin.x
            if x < minX {
                x = minX
            }
            let maxX = weakSelf.maskLineView.frame.origin.x + weakSelf.maskLineView.frame.width
            if x > maxX {
                x = maxX
            }
            let progress = (x - minX) / weakSelf.maskLineView.frame.width
            weakSelf.setProgress(progress)
            switch pan.state {
            case .changed:
                if !weakSelf.isScrollToStep { // 无需校准
                    weakSelf.valueChangeBlock?(progress)
                }
            case .ended:
                if weakSelf.isScrollToStep { // 结束校准
                    weakSelf.scrollToStep(progress)
                }
            default: break
            }
        }
        return gesture
    }()

    /// 值变化
    var valueChangeBlock: YPBlock.OneParam<CGFloat>?

    /// 进度
    var progress: CGFloat = 0 {
        didSet { setProgress(progress) }
    }
    
    /// 进度线高
    var progressLineHeight: CGFloat = 3 {
        didSet { layoutSubviews() }
    }

    /// 进度点位半径
    var progressPointRadius: CGFloat = 4 {
        didSet { layoutSubviews() }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        let maskPath = UIBezierPath()
        // 进度线
        let lineRect: CGRect = .init(x: progressPointRadius,
                                     y: (maskLineView.bounds.height - progressLineHeight) / 2,
                                     width: maskLineView.bounds.width - 2 * progressPointRadius,
                                     height: progressLineHeight)
        maskPath.append(.init(rect: lineRect))
        // 绘制圆点
        let pointY = lineRect.origin.y + lineRect.height / 2
        values.enumerated().forEach { (idx, model) in
            let x = lineRect.width * model.progress + progressPointRadius
            maskPath.append(arcPath(arcCenter: .init(x: x, y: pointY)))
            // 打标签
            let tagTop = maskLineView.frame.origin.y + maskLineView.frame.height + progressPointRadius + 8
            let tagCenterX = x + maskLineView.frame.origin.x
            var label: UILabel?
            if let _label = titleLabels.yp.object(at: idx) {
                label = _label
            } else {
                let _label = UILabel.YP.Create(text: model.title,
                                              font: 15,
                                              color: UIColor.wmc_grayH2_323233,
                                              alignment: .center)
                titleLabels.append(_label)
                addSubview(_label)
                label = _label
            }
            if let label = label {
                label.snp.remakeConstraints { make in
                    make.top.equalTo(tagTop)
                    make.centerX.equalTo(tagCenterX)
                }
            }
        }
        maskLayer.path = maskPath.cgPath
        maskLayer.frame = bounds
        maskLineView.layer.mask = maskLayer
        
        setProgress(progress)
    }

    /// 绘制圆形曲线
    func arcPath(arcCenter: CGPoint) -> UIBezierPath {
        return .init(arcCenter: arcCenter,
                     radius: progressPointRadius,
                     startAngle: 0,
                     endAngle: 2 * CGFloat.pi,
                     clockwise: true)
    }

    func _makeUI() {
        addSubview(maskLineView)
        maskLineView.addSubview(progressLineView)
        addSubview(controlView)
        controlView.addSubview(controlPointView)
        
        maskLineView.backgroundColor = .lightGray

        maskLineView.snp.makeConstraints { make in
            make.top.equalToSuperview()
            make.left.equalTo(20)
            make.right.equalTo(-20)
            make.height.equalTo(30)
        }

        progressLineView.snp.makeConstraints { make in
            make.top.left.bottom.equalToSuperview()
            make.width.equalTo(0.001)
        }

        controlView.snp.makeConstraints { make in
            make.centerY.equalTo(maskLineView)
            make.size.equalTo(50)
            make.centerX.equalTo(maskLineView.snp.left)
        }
        controlView.addGestureRecognizer(panGesture)

        controlPointView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.size.equalTo(1)
        }
        
        
        setControlSize(25)
    }

    /// 滑动校准
    func scrollToStep(_ progress: CGFloat) {
        guard isScrollToStep else { return }
        var recentlyValue: CGFloat = 0
        var minValue: CGFloat = 100
        values.forEach { model in
            let positive = abs(model.progress - progress)
            if minValue > positive {
                minValue = positive
                recentlyValue = model.progress
            }
        }
        setProgress(recentlyValue)
        YPDevice.PlayShake(.light)

        valueChangeBlock?(recentlyValue)
    }

    func setProgress(_ progress: CGFloat) {
        let progressWidth = maskLineView.frame.width * progress
        progressLineView.snp.updateConstraints { make in
            make.width.equalTo(progressWidth)
        }
        let minX = maskLineView.frame.origin.x
        controlView.center.x = progressWidth + minX
    }

    /// 设置控制器大小
    func setControlSize(_ size: CGFloat) {
        controlPointView.layer.cornerRadius = size / 2
        controlPointView.layer.shadowRadius = size / 4
        guard let _ = controlPointView.superview else { return }
        controlPointView.snp.updateConstraints { make in
            make.size.equalTo(size)
        }
    }

    // Private

    /// 值
    private var values: [Model] = []

    /// 是否启用滑动校准
    private var isScrollToStep: Bool = true

    /// 标题组
    private var titleLabels: [UILabel] = []
}
